/* testfiles.c
 *	Simple program to test the file handling system calls
 */

#include "syscall.h"
#define Dim 	20	/* sum total of the arrays doesn't fit in 
			 * physical memory 
			 */
OpenFileId fd;
  int bytesread;
  char buf[30];
  int lockID;
  int condID;
  int newLockIndex;
  int newCondIndex;
  int i;
  char * choice;
  int errorCode;
  int threadReady;
  /*-----------User Variables------------*/
  int MAX_LOCKS;  /* MUST CHANGE TO OS VARIABLE! */
  int MAX_CONDITIONS;
  int MAX_THREADS;
  int testTenLock;
  int testTenCV;
  int threadNum;

	int A[Dim][Dim];
	int B[Dim][Dim];
	int C[Dim][Dim];
	
	int Aa[1024];	/* size of physical memory; with code, we'll run out of space!*/

	int D[Dim][Dim];
	int E[Dim][Dim];
	int F[Dim][Dim];
	
	int Dd[1024];	/* size of physical memory; with code, we'll run out of space!*/

/*Sorting Code duplicated from sort.c for forking*/
void toForkSort()
{
    int j, tmp;

    /* first initiAalize the AarrAay, in reverse sorted order */
    for (i = 0; i < 1024; i++)		
        Aa[i] = 1024 - i;

    /* then sort! */
    for (i = 0; i < 1023; i++){
	
		if(i%100 == 0 && i != 0){
			Printing("%i.\n", ConsoleOutput, i, 0);
			Printing("Finished loops: \0", ConsoleOutput, i, 0);
		}
		else if(i%10 == 0 && i != 0){
			Printing("%i, \0", ConsoleOutput, i, 0);
		}
		else if(i == 0){
			Printing("Finished loops: \0", ConsoleOutput, i, 0);
		}
		
        for (j = i; j < (1023 - i); j++)
	   if (Aa[j] > Aa[j + 1]) {	/* out of order -> need to swAap ! */
	      tmp = Aa[j];
	      Aa[j] = Aa[j + 1];
	      Aa[j + 1] = tmp;
    	   }
	}
    Exit(Aa[0]);		/* and then we're done -- should be 0! */
}

/*Sorting Code duplicated from sort.c for forking*/
void toForkSort2()
{
    int j, tmp;

    /* first initiAalize the AarrAay, in reverse sorted order */
    for (i = 0; i < 1024; i++)		
        Dd[i] = 1024 - i;

    /* then sort! */
    for (i = 0; i < 1023; i++){
		if(i%100 == 0 && i != 0){
			Printing("%i.\n", ConsoleOutput, i, 0);
			Printing("Finished loops: \0", ConsoleOutput, i, 0);
		}
		else if(i%10 == 0 && i != 0){
			Printing("%i, \0", ConsoleOutput, i, 0);
		}
		else if(i == 0){
			Printing("Finished loops: \0", ConsoleOutput, i, 0);
		}
		
        for (j = i; j < (1023 - i); j++)
	   if (Dd[j] > Dd[j + 1]) {	/* out of order -> need to swAap ! */
	      tmp = Dd[j];
	      Dd[j] = Dd[j + 1];
	      Dd[j + 1] = tmp;
    	   }
	}
    Exit(Dd[0]);		/* and then we're done -- should be 0! */
}

/*Matrix Multiplication code duplicated from matmult.c for forking*/
void toForkMatMult()
{
    int j, k;

	
    for (i = 0; i < Dim; i++)		/* first initialize the matrices */
	for (j = 0; j < Dim; j++) {
	     A[i][j] = i;
	     B[i][j] = j;
	     C[i][j] = 0;

	}

	
    for (i = 0; i < Dim; i++){
		Printing("Finished loop: %i.\n", ConsoleOutput, i, 0);
		/* then multiply them together */
		for (j = 0; j < Dim; j++){
            for (k = 0; k < Dim; k++){
				C[i][j] += A[i][k] * B[k][j];				
				/*Printing("One multiply.\n", ConsoleOutput, 0, 0);*/
			}
		 
		 } 
	}

    Exit(C[Dim-1][Dim-1]);		/* and then we're done */
}

void toForkMatMult2()
{
    int j, k;

	
    for (i = 0; i < Dim; i++)		/* first initialize the matrices */
	for (j = 0; j < Dim; j++) {
	     D[i][j] = i;
	     E[i][j] = j;
	     F[i][j] = 0;

	}

	
    for (i = 0; i < Dim; i++){
		Printing("Finished loop: %i.\n", ConsoleOutput, i, 0);
		/* then multiply them together */
		for (j = 0; j < Dim; j++){
            for (k = 0; k < Dim; k++){
				F[i][j] += D[i][k] * E[k][j];				
				/*Printing("One multiply.\n", ConsoleOutput, 0, 0);*/
			}
		 
		 } 
	}

    Exit(F[Dim-1][Dim-1]);		/* and then we're done */
}



/*Test 1: calling fork on matrix multiplication*/
void test1(){

	Printing("Begin: Test 1 - Forking matrix multiplication\n", ConsoleOutput, 0, 0);

	Fork(toForkMatMult);
	
	Printing("End: Test 1\n", ConsoleOutput, 0, 0);	
	

}

/*Test 2: Exec-ing a matrix multiplication*/
void test2(){

	Printing("Begin: Test 2 - Calling exec on matrix multiplication\n", ConsoleOutput, 0, 0);
	
	errorCode = Exec("../test/matmult", 15);
	
	Printing("End: Test 2\n", ConsoleOutput, 0, 0);


}

/*Test 3: Exec-ing a matrix multiplication multiple times*/
void test3(){

	Printing("Begin: Test 3 - Calling exec on matrix multiplication multiple times\n", ConsoleOutput, 0, 0);
	
	errorCode = Exec("../test/matmult", 15);
	
	errorCode = Exec("../test/matmult", 15);

	Printing("End: Test 3\n", ConsoleOutput, 0, 0);


}
	
/*Test 4: Forking Sort*/
void test4(){

	Printing("Begin: Test 4 - Calling fork on sort.\n", ConsoleOutput, 0, 0);

	Fork(toForkSort);
	
	Printing("End: Test 4\n", ConsoleOutput, 0, 0);

}

/*Test 5: Exec-ing sort*/
void test5(){

	Printing("Begin: Test 5 - Calling exec on sort.\n", ConsoleOutput, 0, 0);
	errorCode = Exec("../test/sort", 12);
	Printing("End: Test 5 - Calling exec on sort.\n", ConsoleOutput, 0, 0);

}
	
/*Test 6: Exec-ing sort multiple times*/
void test6(){

	Printing("Begin: Test 6 - Calling exec on sort multiple times.\n", ConsoleOutput, 0, 0);
	errorCode = Exec("../test/sort", 12);
	errorCode = Exec("../test/sort", 12);
	Printing("End: Test 6 - Calling exec on sort multiple times.\n", ConsoleOutput, 0, 0);

}
	

void test7(){

  Printing("Begin: Test 7 - Forking matrix multiplication\n", ConsoleOutput, 0, 0);
  Fork(toForkMatMult2);
	Fork(toForkMatMult);

	
	Printing("End: Test 7\n", ConsoleOutput, 0, 0);		

}	
	
void test8(){
	Printing("Begin: Test 8 - Calling fork on sort.\n", ConsoleOutput, 0, 0);
	Fork(toForkSort2);
	Fork(toForkSort);
	
	Printing("End: Test 8\n", ConsoleOutput, 0, 0);

}
	
void test9(){

}
	
void test10(){

}

void test11(){

}

void test12(){

}

void test13(){

}

void test14(){

}



void test15(){

}

void test16(){

}

void test17(){
	
}

void test18(){ 


}

void test19(){


}
void test20(){

}
void test21(){

}

void test22(){

}

void test23(){

	
}



void submenu3(){
	return;
}

void submenu2(){

	Write("Please choose of the following options.\n", 40, ConsoleOutput);
	Printing("1. \n", ConsoleOutput, 0,0);
	Printing("2. \n", ConsoleOutput, 0,0);
	Printing("3. \n", ConsoleOutput, 0,0);

	Read(choice, 1, ConsoleInput);
	
	if(*choice == '1'){
		test21();
	}
	else if(*choice == '2'){
		test22();
	}
	else if(*choice == '3'){
		test23();
	}
	else{
		Write("Error handling input.\n", 22, ConsoleOutput);
	}
	
	return;

}

void submenu1(){

	Write("Please choose of the following options.\n", 40, ConsoleOutput);
	
	Printing("1. \n", ConsoleOutput, 0,0);
	Printing("2. \n", ConsoleOutput, 0,0);
	Printing("3. \n", ConsoleOutput, 0,0);
	Printing("4. \n", ConsoleOutput, 0,0);
	Printing("5. \n", ConsoleOutput, 0,0);
	Printing("6. \n", ConsoleOutput, 0,0);
	Printing("7. \n", ConsoleOutput, 0,0);
	Printing("8. \n", ConsoleOutput, 0,0);
	Printing("9. \n", ConsoleOutput, 0,0);
	Printing("0. \n", ConsoleOutput, 0,0);	
	Write("n. More...\n", 11, ConsoleOutput);

	Read(choice, 1, ConsoleInput);
	
	if(*choice == '1'){
		test11();
	}
	else if(*choice == '2'){
		test12();
	}
	else if(*choice == '3'){
		test13();
	}
	else if(*choice == '4'){
		test14();
	}
	else if(*choice == '5'){
		test15();
	}
	else if(*choice == '6'){
		test16();
	}
	else if(*choice == '7'){
		test17();
	}
	else if(*choice == '8'){
		test18();
	}
	else if(*choice == '9'){
		test19();
	}
	else if(*choice == '0'){
		test20();
	}
	else if(*choice == 'n'){
		submenu2();
	}
	else{
		Write("Error handling input.\n", 22, ConsoleOutput);
	}
	
	return;

}
	
void menu(){

	Write("Please choose of the following options.\n", 40, ConsoleOutput);

	Printing("1. Start fork on matrix multiplication\n", ConsoleOutput, 0,0);
	Printing("2. Start exec on matrix multiplication\n", ConsoleOutput, 0,0);
	Printing("3. Start exec multiple times on matrix multiplication\n", ConsoleOutput, 0,0);
	Printing("4. Start fork on sort\n", ConsoleOutput, 0,0);
	Printing("5. Start exec on sort\n", ConsoleOutput, 0,0);
	Printing("6. Start exec multiple times on sort\n", ConsoleOutput, 0,0);
	Printing("7. Start fork twice on matrix multiplication.\n", ConsoleOutput, 0,0);
	Printing("8. Start fork twice on sort.\n", ConsoleOutput, 0,0);
	Printing("9. \n", ConsoleOutput, 0,0);
	Printing("0. \n", ConsoleOutput, 0,0);
	Printing("n. \n", ConsoleOutput, 0,0);

	Write("\n\nNote: only the first digit that you enter will be read.  \nFor example, input 456 will be read as choice 4.\n", 109, ConsoleOutput);
	Read(choice, 1, ConsoleInput);
	
	if(*choice == '1'){
		test1();
	}
	else if(*choice == '2'){
		test2();
	}
	else if(*choice == '3'){
		test3();
	}
	else if(*choice == '4'){
		test4();
	}
	else if(*choice == '5'){
		test5();
	}
	else if(*choice == '6'){
		test6();
	}
	else if(*choice == '7'){
		test7();
	}
	else if(*choice == '8'){
		test8();
	}
	else if(*choice == '9'){
		test9();
	}
	else if(*choice == '0'){
		test10();
	}
	else if(*choice == 'n'){
		/*submenu1();*/
	}
	else{
		Write("Error handling input.\n", 22, ConsoleOutput);
	}
	return;
}

int main() {



   /* Create("testfile", 8);
    fd = Open("testfile", 8);

    Write("testing a write\n", 16, fd );
	Write("Starting\n", 9, ConsoleOutput);
    Close(fd);


    fd = Open("testfile", 8);
    bytesread = Read( buf, 100, fd );
    Write( buf, bytesread, ConsoleOutput );
    Close(fd);
	*/
	
	menu();
	Exit(0);
}	

